/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 * 
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package jmmos.gameserver.model.itemcontainer;

import javolution.util.FastList;

import jmmos.Config;
import jmmos.gameserver.model.MMOGuild;
import jmmos.gameserver.model.actor.instance.MMOPcInstance;
import jmmos.gameserver.model.items.instance.MMOItemInstance;
import jmmos.gameserver.model.items.instance.MMOItemInstance.ItemLocation;
import jmmos.gameserver.scripting.scriptengine.events.GuildWarehouseAddItemEvent;
import jmmos.gameserver.scripting.scriptengine.events.GuildWarehouseDeleteItemEvent;
import jmmos.gameserver.scripting.scriptengine.events.GuildWarehouseTransferEvent;
import jmmos.gameserver.scripting.scriptengine.listeners.guild.GuildWarehouseListener;

public final class GuildWarehouse extends Warehouse
{
	private final MMOGuild _guild;
	
	private final FastList<GuildWarehouseListener> guildWarehouseListeners = new FastList<GuildWarehouseListener>().shared();
	
	public GuildWarehouse(MMOGuild guild)
	{
		_guild = guild;
	}
	
	@Override
	public String getName()
	{
		return "GuildWarehouse";
	}
	
	@Override
	public int getOwnerId()
	{
		return _guild.getGuildId();
	}
	
	@Override
	public MMOPcInstance getOwner()
	{
		return _guild.getLeader().getPlayerInstance();
	}
	
	@Override
	public ItemLocation getBaseLocation()
	{
		return ItemLocation.GUILDWH;
	}
	
	public String getLocationId()
	{
		return "0";
	}
	
	public int getLocationId(boolean dummy)
	{
		return 0;
	}
	
	public void setLocationId(MMOPcInstance dummy)
	{
	}
	
	@Override
	public boolean validateCapacity(long slots)
	{
		return ((_items.size() + slots) <= Config.WAREHOUSE_SLOTS_GUILD);
	}
	
	@Override
	public MMOItemInstance addItem(String process, int itemId, long count, MMOPcInstance actor, Object reference)
	{
		MMOItemInstance item = getItemByItemId(itemId);
		if (!fireGuildWarehouseAddItemListeners(process, item, actor, count))
		{
			return null;
		}
		return super.addItem(process, itemId, count, actor, reference);
	}
	
	@Override
	public MMOItemInstance addItem(String process, MMOItemInstance item, MMOPcInstance actor, Object reference)
	{
		if (!fireGuildWarehouseAddItemListeners(process, item, actor, item.getCount()))
		{
			return null;
		}
		return super.addItem(process, item, actor, reference);
	}
	
	@Override
	public MMOItemInstance destroyItem(String process, MMOItemInstance item, long count, MMOPcInstance actor, Object reference)
	{
		if (!fireGuildWarehouseDeleteItemListeners(process, item, actor, count))
		{
			return null;
		}
		return super.destroyItem(process, item, count, actor, reference);
	}
	
	@Override
	public MMOItemInstance transferItem(String process, int objectId, long count, ItemContainer target, MMOPcInstance actor, Object reference)
	{
		MMOItemInstance sourceitem = getItemByObjectId(objectId);
		if (!fireGuildWarehouseTransferListeners(process, sourceitem, count, target, actor))
		{
			return null;
		}
		return super.transferItem(process, objectId, count, target, actor, reference);
	}
	
	// Listeners
	/**
	 * Fires all the GuildWarehouse add item listeners, if any.<br>
	 * Action is cancelled if it returns false
	 * @param process
	 * @param item
	 * @param actor
	 * @param count
	 * @return
	 */
	private boolean fireGuildWarehouseAddItemListeners(String process, MMOItemInstance item, MMOPcInstance actor, long count)
	{
		if (!guildWarehouseListeners.isEmpty() && (actor != null) && (item != null))
		{
			GuildWarehouseAddItemEvent event = new GuildWarehouseAddItemEvent();
			event.setActor(actor);
			event.setItem(item);
			event.setCount(count);
			event.setProcess(process);
			for (GuildWarehouseListener listener : guildWarehouseListeners)
			{
				if (!listener.onAddItem(event))
				{
					return false;
				}
			}
		}
		return true;
	}
	
	/**
	 * Fires all the GuildWarehouse delete item listeners, if any.<br>
	 * Action is cancelled if it returns false
	 * @param process
	 * @param item
	 * @param actor
	 * @param count
	 * @return
	 */
	private boolean fireGuildWarehouseDeleteItemListeners(String process, MMOItemInstance item, MMOPcInstance actor, long count)
	{
		if (!guildWarehouseListeners.isEmpty() && (actor != null) && (item != null))
		{
			GuildWarehouseDeleteItemEvent event = new GuildWarehouseDeleteItemEvent();
			event.setActor(actor);
			event.setCount(count);
			event.setItem(item);
			event.setProcess(process);
			for (GuildWarehouseListener listener : guildWarehouseListeners)
			{
				if (!listener.onDeleteItem(event))
				{
					return false;
				}
			}
		}
		return true;
	}
	
	/**
	 * Fires all the GuildWarehouse transfer listeners, if any.<br>
	 * Action is cancelled if it returns false
	 * @param process
	 * @param item
	 * @param count
	 * @param target
	 * @param actor
	 * @return
	 */
	private boolean fireGuildWarehouseTransferListeners(String process, MMOItemInstance item, long count, ItemContainer target, MMOPcInstance actor)
	{
		if (!guildWarehouseListeners.isEmpty() && (actor != null) && (item != null) && (target != null))
		{
			GuildWarehouseTransferEvent event = new GuildWarehouseTransferEvent();
			event.setActor(actor);
			event.setCount(count);
			event.setItem(item);
			event.setProcess(process);
			event.setTarget(target);
			for (GuildWarehouseListener listener : guildWarehouseListeners)
			{
				if (!listener.onTransferItem(event))
				{
					return false;
				}
			}
		}
		return true;
	}
	
	/**
	 * Adds a guild warehouse listener
	 * @param listener
	 */
	public void addWarehouseListener(GuildWarehouseListener listener)
	{
		if (!guildWarehouseListeners.contains(listener))
		{
			guildWarehouseListeners.add(listener);
		}
	}
	
	/**
	 * Removes a guild warehouse listener
	 * @param listener
	 */
	public void removeWarehouseListener(GuildWarehouseListener listener)
	{
		guildWarehouseListeners.remove(listener);
	}
}
